/*
Copyright 2011, CSE Shareware Foundation
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, 
   this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, 
   this list of conditions and the following disclaimer in the documentation 
   and/or other materials provided with the distribution.
 * Neither the name of CSE Shareware Foundation nor the names of its contributors 
   may be used to endorse or promote products derived from this software without 
   specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef _PLATFORM_H_CSEAPI_
#define _PLATFORM_H_CSEAPI_

#include "setup.h"

#ifdef _DEBUG
  #ifndef DEBUG
    #define DEBUG
  #endif
#endif

#ifdef DEBUG
  #ifndef _DEBUG
    #define _DEBUG
  #endif
#endif

#ifdef WINCE
  #undef  WINVER
  #define WINVER _WIN32_WCE

  #ifndef VC_EXTRALEAN
    #define VC_EXTRALEAN
  #endif

  #include <ceconfig.h>
  #if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
    #define SHELL_AYGSHELL
  #endif

  #if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
    #ifndef _DEVICE_RESOLUTION_AWARE
      #define _DEVICE_RESOLUTION_AWARE
    #endif
  #endif

  #ifdef _DEVICE_RESOLUTION_AWARE
    #include "DeviceResolutionAware.h"
  #endif

  #include <aygshell.h>
  #pragma comment(lib, "aygshell.lib") 

  #if (_WIN32_WCE < 0x500) && ( defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP) )
    #pragma comment(lib, "ccrtrtti.lib")
    #ifdef _X86_
        #if defined(_DEBUG)
            #pragma comment(lib, "libcmtx86d.lib")
        #else
            #pragma comment(lib, "libcmtx86.lib")
        #endif
    #endif
  #endif

  #include <altcecrt.h>

  #undef  CSE_USE_UNICODE
  #define CSE_USE_UNICODE          1   // WinCE only support unicode
#endif

#include <limits.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>

#define CSE_USE_PLATFORM           1
#include "CseTypes.h"

#if defined(__VISUALC__)
  #pragma warning(disable: 4996)
#endif

#if defined(__VISUALC__) || defined(__MINGW32__)
  #define CSE_STDCALL              __stdcall
  #define CSE_CDECL                __cdecl
  #define CSE_EXPORT               __declspec(dllexport)
  #define CSE_IMPORT               __declspec(dllimport)

  #define CseLongLongFmtSpec       _T("I64")
  #define CsePathSpliter           _T('\\')
#elif defined(__GNUC__)
  #define CSE_STDCALL              __attribute__((stdcall))
  #define CSE_CDECL                __attribute__((cdecl))
  #if __GNUC__ >= 4
    #define CSE_EXPORT             __attribute__((visibility("default")))
    #define CSE_IMPORT
  #else
    #define CSE_EXPORT             __attribute__((dllexport))
    #define CSE_IMPORT             __attribute__((dllimport))
  #endif
  
  #define CseLongLongFmtSpec       _T("ll")  // used in linux
  #define CsePathSpliter           _T('/')
#else
  #error "Compiler not support yet!"
#endif

#ifdef CSEAPI_EXPORTS              // Export CSE kernel API
  #define CSE_IMPEXP_IN            CSE_EXPORT
#elif CSE_STATIC_LINK              // Static link CSE kernel
  #define CSE_IMPEXP_IN
#else                              // Import CSE kernel from DLL
  #define CSE_IMPEXP_IN            CSE_IMPORT
#endif
#define CSE_IMPEXP_OUT             CSE_EXPORT

#undef  CHECK_MSG
#undef  CHECK_TRUE
#define CHECK_MSG(b,desc)          (b? 0: Cse_AssertMsg(0,desc))
#define CHECK_TRUE(b)              (b? 0: Cse_AssertMsg2(0,__LINE__,_T(__FILE__)))

#undef WAIT_TO_DO
#define WAIT_TO_DO()               throw Cse_WaitToDo(__LINE__,_T(__FILE__))

#undef ASSERT_MSG
#undef ASSERT_TRUE
#ifdef _DEBUG
  #define ASSERT_MSG(b,desc)       Cse_AssertMsg(b,desc)
  #define ASSERT_TRUE(b)           CHECK_TRUE(b)
#else
  #define ASSERT_MSG
  #define ASSERT_TRUE
#endif

#if CSE_USE_ERR_LOG
  #if defined(_UNICODE)
    #define LOG_MSG                wprintf
  #else
    #define LOG_MSG                printf
  #endif
#else
  #define LOG_MSG
#endif

#ifdef _DEBUG
  #define STATIC
  #define LOG_DBG_MSG              LOG_MSG
#else
  #define STATIC                   static
  #define LOG_DBG_MSG
#endif

#define CSE_PRINT                  CsePrint
#define APP_ARGUMENTS()            CseRegister->get(_T("KERNEL/ARGS"))

// following (ansi function) is supported by C99 standard
#ifdef _UNICODE
  #define PRINTF                   wprintf
  #define STRCPY                   wcscpy
  #define STRNCPY                  wcsncpy
  #define STRSTR                   wcsstr
  #define STRCMP                   wcscmp
  #define STRNCMP                  wcsncmp
  #define SPRINTF                  swprintf
  #define VSPRINTF                 vswprintf
  #define STRLEN                   wcslen
  #define STRCAT                   wcscat
  #define SCANF                    wscanf
  #define SSCANF                   swscanf
  #define GETCHAR                  getwchar
  
  #define FGETS                    fgetws
  #define FSCANF                   fwscanf
  #define STRTOL                   wcstol
  #define STRTOUL                  wcstoul
  #define STRTOD(x,ptr)            wcstod(x,ptr)
#else
  #define PRINTF                   printf
  #define STRCPY                   strcpy
  #define STRNCPY                  strncpy
  #define STRSTR                   strstr
  #define STRCMP                   strcmp
  #define STRNCMP                  strncmp
  #define SPRINTF                  sprintf
  #define VSPRINTF                 vsprintf
  #define STRLEN                   strlen
  #define STRCAT                   strcat
  #define SCANF                    scanf
  #define SSCANF                   sscanf
  #define GETCHAR                  getchar
  
  #define FGETS                    fgets
  #define FSCANF                   fscanf
  #define STRTOL                   strtol
  #define STRTOUL                  strtoul
  #define STRTOD(x,ptr)            strtod(x,ptr)
#endif

class TCseException;  // forward declare
extern CSE_IMPEXP_IN TBool Cse_AssertMsg(int expr, const TXchar *msg);
extern CSE_IMPEXP_IN TBool Cse_AssertMsg2(int expr, int iLine, const TXchar *sFile);
extern CSE_IMPEXP_IN TCseException Cse_WaitToDo(int line, const TXchar *sFile);

extern CSE_IMPEXP_IN TInt32 READ_FLAG(TInt32 iFlag, int iOffset, int n);
extern CSE_IMPEXP_IN TInt32 MAKE_FLAG(TInt32 iFlag, TInt32 iValue, int iOffset, int n);

#define CUT_FROM                   20051206  // The date CSE V1 first released

#endif
